/*
	File:		Game.h
	Course:		SGD 1301
	Author:		Peter Nguyen
	Purpose:	CGame class controls the SGD Wrappers
				and the game logic
*/

#pragma once

#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <stack>
using std::stack;

////////////////////////////////////////////////////////////
// SGD Wrappers
// - forward class declaration to reduce header dependencies
// - can ONLY create pointers and references
class CSGD_Direct3D;
class CSGD_DirectInput;
class CSGD_TextureManager;
class CSGD_XAudio2;

class CBitmapFont;

class IGameState;


////////////////////////////////////////////////////////////
// CGame class
//	- singleton object
//	- manages the SGD wrappers
class CGame
{
public:
	////////////////////////////////////////////////////////
	// SINGLETON
	//	- only ONE object can be created at any given time
	//	- has an accessor to that object
	static CGame*	GetInstance( void );
	static void		DeleteInstance( void );
	static bool DEBUG_MODE;
	
	////////////////////////////////////////////////////////
	// 3 major steps: Setup, Play, Cleanup

	// Setup:
	void Initialize( HWND hWnd, HINSTANCE hInstance,
					 int nWidth, int nHeight, bool bIsWindowed );

	// Play
	bool Main( void );

	// Cleanup:
	void Shutdown( void );

	
	////////////////////////////////////////////////////////
	// Window Accessors
	int	 GetWidth	( void ) const	{ return m_nScreenWidth;	}
	int  GetHeight	( void ) const	{ return m_nScreenHeight;	}
	bool IsWindowed	( void ) const	{ return m_bIsWindowed;		}
	
	////////////////////////////////////////////////////////
	// Font Accessors
	CBitmapFont*	GetFont( void ) const	{	return m_pFont;	}

	
	// Game State Machine
	void PushState( IGameState* pNewState);
	void PopState();
	IGameState*	TopState();
	//void ChangeState( IGameState* pNewState );

	// Windows Helpers
	bool CheckToggleFullScreen();

	////////////////////////////////////////////////////////
	//Accessors
	int		GetWorldWidth	( void ) const	{	return m_nWorldWidth	;		}
	int		GetWorldHeight	( void ) const	{	return m_nWorldHeight	;		}
	int		GetCameraX		( void ) const	{	return m_nCameraX		;		}
	int		GetCameraY		( void ) const	{	return m_nCameraY		;		}
	float	GetCameraRotation( void ) const	{	return m_nCameraRotation;		}
	int	GetIsFullscreen( void ) const	{	return m_bIsFullscreen;		}
	int	GetSoundVolume( void ) const	{	return m_bSoundVolume;		}
	int	GetBGMVolume( void ) const	{	return m_bBGMVolume;		}
	int	GetScore( void ) const	{	return m_nScore;		}

	void	SetWorldWidth 	( int WorldWidth 	)	{	m_nWorldWidth	= WorldWidth; }
	void	SetWorldHeight	( int WorldHeight	)	{	m_nWorldHeight	= WorldHeight;}
	void	SetCameraX		( int CameraX		)	{	m_nCameraX		= CameraX	;}
	void	SetCameraY		( int CameraY		)	{	m_nCameraY		= CameraY	;}
	void	SetCameraRotation( float CameraRotation		)	{	m_nCameraRotation		= CameraRotation	;}
	void	SetIsFullscreen( int IsFullscreen		)	{	m_bIsFullscreen		= IsFullscreen	;}
	void	SetSoundVolume( int SoundVolume		);
	void	SetBGMVolume( int BGMVolume		);
	void	SetScore( int Score		)	{	m_nScore		= Score;}
	void	ChangeScore( int Change );

private:
	////////////////////////////////////////////////////////
	// SINGLETON
	//	- dynamically allocated object
	//	- private constructors / destructor / assignment operator
	//	  prevents any other class from creating an object
	static CGame*	s_pInstance;
	CGame( void );
	~CGame( void );
	CGame( const CGame& );				//	= delete;
	CGame& operator= ( const CGame& );	//	= delete;
	
	////////////////////////////////////////////////////////
	// Camera infomation
	int						m_nCameraX	  ;
	int						m_nCameraY	  ;
	float					m_nCameraRotation;
	
	////////////////////////////////////////////////////////
	// World infomation
	int						m_nWorldWidth ;
	int						m_nWorldHeight;

	////////////////////////////////////////////////////////
	//Windows infomation
	int						m_bIsFullscreen;
	
	////////////////////////////////////////////////////////
	//Audio infomation
	int						m_bSoundVolume;
	int						m_bBGMVolume;


	////////////////////////////////////////////////////////
	// Helper methods to play the game
	bool	Input ( void );
	void	Update( void );
	void	Render( void );


	
	////////////////////////////////////////////////////////
	// SGD Wrappers
	CSGD_Direct3D*			m_pD3D;
	CSGD_DirectInput*		m_pDI;
	CSGD_TextureManager*	m_pTM;
	CSGD_XAudio2*			m_pXA;

	// Other Wrappers
	CBitmapFont*			m_pFont;

	
	////////////////////////////////////////////////////////
	// Window Attributes
	int						m_nScreenWidth;
	int						m_nScreenHeight;
	bool					m_bIsWindowed;


	// Current time
	DWORD					m_dwCurrTime;


	// State Stack
	stack<IGameState*>		m_sStateStack;

	// Current state
	IGameState*				m_pCurrState;


	////////////////////////////////////////////////////////
	// Game Info
	int						m_nScore;

};

